//
//  main.m
//  08_Code iOS9新特性(Nullability 泛型 _kindof)
//
//  Created by dllo on 16/7/13.
//  Copyright © 2016年 yh. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Persson.h"
#import "Truck.h"
#import "Student.h"

int main(int argc, const char * argv[]) {
    Persson *per1 = [[Persson alloc] init];
#if 0
    // nonnull 修饰属性 对应的getter和setter方法
    per1.name = nil; // 不能为空
    per1.name = @"zhoahao";
    per1.size = nil; // 不能为空
    // nullable 修饰属性 对应的getter和setter方法
    //    [per1 setSex:<#(NSString * _Nullable)#>];
    per1.study = nil;
    // null_resettable
//    [per1 setFriends:<#(NSArray * _Nullable)#>] set 方法可以为空值
//    [per1 friends];  getter 方法是nonnull
    per1.friends = nil;
    
//    [per1 setDic:<#(NSDictionary * _Nonnull)#>]  不为空
    // 2. 泛型
    // 带泛型的容器 (规定了容器中所存储的类型 数组中添加其他类型会有警告 数组中取出的类型不再是id类型 泛型会改变类的一些方法 与之声明的方法相同) (例如: 声明一个可变数组内部存放的都是字符串 不能放其他类型)
    NSMutableArray *array1 = [NSMutableArray arrayWithObjects:@"zhaohao", nil];
    NSMutableArray<NSString *> *array = [NSMutableArray arrayWithObjects:@"123", nil];
//    array1.lastObject.                 id 类型 没有length属性
//    array.lastObject.length          NSString类型 有length
    [array addObject:@" "];
//    [array addObject:@20];
//    [array addObject:per1];
    
    NSMutableDictionary<NSString *, NSString *> *dic = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"zhaohao", @"name", nil];
    NSInteger len = [dic objectForKey:@"name"].length;
    NSLog(@"%ld", len);
#endif

    Truck<Persson *> *truck = [[Truck alloc] init];
    [truck addObject:per1];

    Student *stu = [[Student alloc] init];
    stu.stuNumber = @"0007";
    
    Truck<Student *> *truckStu = [[Truck alloc] init];
    [truckStu addObject:stu];
    [truckStu addObject:per1];
    
    // 协变性 与 逆变性
    Truck *oneTruck = nil;
    Truck<NSArray *> *truck1 = nil;
    Truck<NSMutableArray *> *truck2 = nil;
    // 大类型(任意类型) 可赋值给任意类型 任意类型也可赋值给大类型
    oneTruck = truck1;
    oneTruck = truck2;
    truck1 = oneTruck;
    truck2 = oneTruck;
    // __covariant 协变性 子类在给父类赋值时 自动强转
    truck1 = truck2;
    // __contravariant 逆变性 父类给子类赋值 自动强转
    truck2 = truck1;
    
    // 3. __kindOf
    Truck *truckKindOf = [[Truck alloc] init];
//    NSMutableArray *arr = (NSMutableArray *)[truckKindOf returnArray]; // 强转
    NSArray *arr1 = [truckKindOf returnArray];
    
    
    return 0;
    
    
    
    
    
}
